<template>
<div class="x-form">
  <template v-for="(item, index) in rules" :key="'form'+index">
    <div class="col" v-if="typeof item.hide === 'undefined' || item.hide === false"
         :style="{ width: typeof item.width === 'undefined'
      ? '100%'
      : (typeof item.width ==='number' ? (item.width+'px'): `${item.width}`), marginLeft: typeof item.marginLeft!=='undefined'?item.marginLeft+'px': '0px'
    }">
      <table>
        <tbody>
        <tr>
          <td :style="{width: titleWidth+'px'}" v-if="item.title">
            <div class="title" >
              <span class="required" v-if="item.required">*</span>{{item.title}}
            </div>
          </td>
          <td >
            <template  v-if="item.com ==='JInput'">
              <JInput
                  :ref="el=>getRef(el, item.field)"
                  v-bind="item"
                  v-model="formModel[item.field]"
                  v-on="(typeof item.events !== 'undefined') ? item.events : noneEvents"
              />
            </template>
            <template  v-if="item.com ==='JGrid'">
              <j-grid
                  :ref="el=>getRef(el, item.field)"
                  v-bind="item"
                  v-model="formModel[item.field]"
                  v-on="(typeof item.events !== 'undefined') ? item.events : noneEvents"
              />
            </template>
            <template  v-if="item.com ==='JLabel'">
              <JLabel
                  :ref="el=>getRef(el, item.field)"
                  v-bind="item"
                  v-model="formModel[item.field]"
                  v-on="(typeof item.events !== 'undefined') ? item.events : noneEvents"
              />
            </template>
            <template  v-if="item.com ==='billTitle'">
              <bill-title
                  :ref="el=>getRef(el, item.field)"
                  v-model="formModel[item.field]"
                  v-bind="item"
                  v-on="(typeof item.events !== 'undefined') ? item.events : noneEvents"
              />
            </template>
            <template  v-if="item.com ==='billPrinted'">
              <bill-printed
                  :ref="el=>getRef(el, item.field)"
                  v-bind="item"
                  v-model="formModel[item.field]"
                  v-on="(typeof item.events !== 'undefined') ? item.events : noneEvents"
              />
            </template>
            <template  v-if="item.com ==='billState'">
              <bill-state
                  :ref="el=>getRef(el, item.field)"
                  v-bind="item"
                  v-model="formModel[item.field]"
                  v-on="(typeof item.events !== 'undefined') ? item.events : noneEvents"
              />
            </template>
            <template  v-if="item.com ==='JPicker'" >
              <j-picker
                  :ref="el=>getRef(el, item.field)"
                  v-bind="item"
                  v-model="formModel[item.field]"
                  v-on="(typeof item.events !== 'undefined') ? item.events : noneEvents"
              />
            </template>
            <template  v-if="item.com ==='JTab'">
              <j-tab
                  :ref="el=>getRef(el, item.field)"
                  v-bind="item"
                  v-model="formModel[item.field]"
                  v-on="(typeof item.events !== 'undefined') ? item.events : noneEvents"
              />
            </template>
            <template  v-if="item.com ==='JButton'">
              <j-button
                  :ref="el=>getRef(el, item.field)"
                  v-bind="item"
                  v-on="(typeof item.events !== 'undefined') ? item.events : noneEvents"
              />
            </template>
            <template  v-if="item.com ==='JCheck'">
              <j-check
                  :ref="el=>getRef(el, item.field)"
                  v-bind="item"
                  v-model="formModel[item.field]"
                  v-on="(typeof item.events !== 'undefined') ? item.events : noneEvents"
              />
            </template>
            <template  v-if="item.com ==='TinyDivider'">
              <div class="divider" :ref="el=>getRef(el, item.field)" />
            </template>
            <template  v-if="item.com ==='ysSel'">
              <ysSel
                  :ref="el=>getRef(el, item.field)"
                  v-bind="item"
                  v-model="formModel[item.field]"
                  v-model:ye="formModel.ye"
                  v-model:ye1="formModel.ye1"
                  v-on="(typeof item.events !== 'undefined') ? item.events : noneEvents"
              />
            </template>
            <template  v-if="item.com ==='JAuto'">
              <j-auto
                  :ref="el=>getRef(el, item.field)"
                  v-bind="item"
                  v-model="formModel[item.field]"
                  v-model:id="formModel[item.idField]"
                  v-on="(typeof item.events !== 'undefined') ? item.events : noneEvents"
              />
            </template>
            <template  v-if="item.com ==='JSelect'">
              <j-select
                  :ref="el=>getRef(el, item.field)"
                  v-bind="item"
                  v-model="formModel[item.idField?item.idField:item.field]"
                  v-on="(typeof item.events !== 'undefined') ? item.events : noneEvents"
              />
            </template>
            <template  v-if="item.com ==='JSelectTree'">
              <j-select-tree
                  :ref="el=>getRef(el, item.field)"
                  v-bind="item"
                  v-model="formModel[item.idField]"
                  v-model:code="formModel[item.catCode]"
                  v-model:name="formModel[item.field]"
                  v-on="(typeof item.events !== 'undefined') ? item.events : noneEvents"
              />
            </template>
            <template  v-if="item.com ==='JTree'">
              <j-tree
                  :ref="el=>getRef(el, item.field)"
                  v-bind="item"
                  v-model="formModel[item.field]"
                  v-on="(typeof item.events !== 'undefined') ? item.events : noneEvents"
              />
            </template>
            <template  v-if="item.com ==='JExport'">
              <j-export
                  :ref="el=>getRef(el, item.field)"
                  v-bind="item"
                  v-model="formModel[item.field]"
                  v-model:id="formModel[item.idField]"
                  v-on="(typeof item.events !== 'undefined') ? item.events : noneEvents"
              />
            </template>
            <template  v-if="item.com ==='JDeliver'">
              <j-deliver
                  :ref="el=>getRef(el, item.field)"
                  v-bind="item"
                  v-model="formModel[item.field]"
                  v-model:id="formModel[item.idField]"
                  v-on="(typeof item.events !== 'undefined') ? item.events : noneEvents"
              />
            </template>
            <template  v-if="item.com ==='JDropbtn'">
              <j-dropbtn
                  :ref="el=>getRef(el, item.field)"
                  v-bind="item"
                  v-model="formModel[item.field]"
                  v-on="(typeof item.events !== 'undefined') ? item.events : noneEvents"
              />
            </template>
            <template  v-if="item.com ==='JPager'">
              <j-pager
                  :ref="el=>getRef(el, item.field)"
                  v-bind="item"
                  v-model="formModel[item.field]"
                  v-on="(typeof item.events !== 'undefined') ? item.events : noneEvents"
              />
            </template>
            <template  v-if="item.com ==='JCode'">
              <j-code
                  :ref="el=>getRef(el, item.field)"
                  v-model="formModel.id"
                  v-model:transType="formModel.transType"
              />
            </template>
            <template  v-if="item.com ==='div'">
              <div :style="item.style">{{formModel[item.field]}}</div>
            </template>
            <template  v-if="item.com ==='des'">
              <div :style="item.style">{{item.val}}</div>
            </template>
            <template  v-if="item.com ==='newrow'">
              <div :style="item.style"></div>
            </template>
            <template  v-if="item.com ==='JLink'">
              <j-link
                  :ref="el=>getRef(el, item.field)"
                  v-bind="item"
                  v-model="formModel[item.field]"
                  v-on="(typeof item.events !== 'undefined') ? item.events : noneEvents"
              />
            </template>
            <template  v-if="item.com ==='XForm'">
              <x-form
                  :ref="el=>getRef(el, item.field)"
                  v-bind="item"
                  v-model="formModel[item.field]"
                  v-model:api="formModel[item.apiField]"
                  v-on="(typeof item.events !== 'undefined') ? item.events : noneEvents"
              />
            </template>
          </td>
        </tr>
        </tbody>
      </table>
    </div>
  </template>
</div>

</template>

<script setup>
import {ref, onMounted, onBeforeMount, nextTick} from "vue";
import XForm from "@/lui/XForm.vue";
import tool from "@/utils/tool";
import JTree from "@/lui/JTree.vue";
import JExport from "@/lui/JExport.vue";
import JSelect from "@/lui/JSelect.vue";
import JCheck from "@/lui/JCheck.vue";
import JAuto from "@/lui/JAuto.vue";
import JPager from "@/lui/JPager.vue";
import JCode from "@/lui/codeBar.vue";
import JDeliver from "@/lui/JDeliver.vue";
import JInput from '@/lui/JInput.vue'
import JSelectTree from "@/lui/JSelectTree.vue";
import ysSel from "@/lui/ysSel.vue";
import JTab from "@/lui/JTab.vue";
import JPicker from "@/lui/JPicker.vue";
import billPrinted from "@/lui/billPrinted.vue";
import billTitle from "@/lui/billTitle.vue";
import billState from "@/lui/billState.vue";
import JLabel from "@/lui/JLabel.vue";
import JGrid from "@/lui/JGrid.vue";
import JButton from "@/lui/JButton.vue";
import JDropbtn from "@/lui/JDropbtn.vue";
import JLink from "@/lui/JLink.vue";

const props = defineProps({
  titleWidth: {type: Number, default: 70},
  size: {type: String, default: 'medium'},
  rules: {type: Array, default: () => {return []}},
})

const noneEvents = {}
const emit = defineEmits(['mounted'])
const formModel = defineModel({})
const api = defineModel('api')
let initModelBak = {}
// 组件ref集合
const refs = ref({})
// 如果有默认值，则设置默认

api.value = {
  exec: (field, action, val) => {
    if(typeof refs.value[field] !== 'undefined') {
      if(typeof refs.value[field][action] !== 'undefined' && typeof refs.value[field][action] === 'function') {
        return  refs.value[field][action](val)
      }
    }
    return null
  },
  getValue: (field) => {
    if(typeof formModel.value[field] !== 'undefined') {
      return formModel.value[field]
    }
    return null
  },
  setValue: (field, val) => {
    for (let i = 0; i < props.rules.length; i++) {
      if(props.rules[i].field === field) {
        formModel.value[field] = val
        break
      }
    }
  },
  getFormData: () => {
    return formModel.value
  },
  setFormData: (data) => {
    formModel.value = data
  },
  disabled: (dis) => {
    if(dis) {
      props.rules.map(row => {
        row.disabled = true
      })
    }
    else {
      props.rules.map(row => {
        row.disabled = false
      })
    }
  },
  readonly: (dis) => {
    if(dis) {
      props.rules.map(row => {
        row.readonly = true
      })
    }
    else {
      props.rules.map(row => {
        row.readonly = false
      })
    }
  },
  resetFields: () => {
    formModel.value = tool.xe.clone(initModelBak, true)
  },
  getRule: (field) => {
    for (let i = 0; i < props.rules.length; i++) {
      if(props.rules[i].field === field) {
        return tool.xe.clone(props.rules[i], true)
      }
    }
  },
  removeRule: (field) => {
    for (let i = 0; i < props.rules.length; i++) {
      if(props.rules[i].field === field) {
        props.rules.splice(i, 1)
      }
    }
  },
  append: (rule) => {
    props.rules.push(rule)
  },
  hide: (field) => {
    props.rules.map(row => {
      if(row.field === field) row.hide = true
    })
  },
  show: (field) => {
    props.rules.map(row => {
      if(row.field === field) row.hide = false
    })
  },
  valid: () => {
    for (let i = 0; i < props.rules.length; i++) {
      let col = props.rules[i]
      if(typeof col.field !== 'undefined') {
        if(typeof col.required !== 'undefined' && col.required === true) {
          if(typeof formModel.value[col.field] === 'undefined' || !formModel.value[col.field]) {
            api.value.exec(col.field, 'focus')
            tool.err(col.title + ' 不能为空')
            return false
          }
          if(typeof col.idField !== 'undefined') {
            if(typeof formModel.value[col.idField] === 'undefined' || !formModel.value[col.idField]) {
              api.value.exec(col.field, 'focus')
              tool.err(col.title + ' 不能为空')
              return false
            }
          }
        }

        if(typeof col.idField !== 'undefined') {
          if(formModel.value[col.field] && !formModel.value[col.idField]) {
            tool.err(col.title + ' 未选择')
            return false
          }
          if(!formModel.value[col.field] && formModel.value[col.idField]) {
            tool.err(col.title + ' 未选择')
            return false
          }
        }
      }
    }
    return true
  }
}
const setDefaultValue = () => {
  for (let i = 0; i < props.rules.length; i++) {
    let item = props.rules[i]
    if(typeof item.field !== 'undefined') {
      let field = item.field
      // 设置默认值
      if(typeof formModel.value[field] === 'undefined') {
        if(typeof item.defaultValue !== 'undefined') {
          formModel.value[item.field] = item.defaultValue
        }
        if(typeof item.defaultId !== 'undefined') {
          formModel.value[item.idField] = item.defaultId
        }
      }
    }
  }
}
// 设置ref名称
const getRef = (el, field) => {
  if(el) {
    refs.value[field] = el
  }
}
// 所有集合 供调用

onBeforeMount(() => {
  setDefaultValue()
  nextTick(() => {
    initModelBak = tool.xe.clone(formModel.value, true)
  })
})

const setDefaultApi = () => {
  for (let i = 0; i < props.rules.length; i++) {
    if(typeof props.rules[i].inject !== 'undefined' && props.rules[i].inject === true) {
      api.value.exec(props.rules[i].field, 'setApi', api.value)
    }
  }
}

onMounted(() => {
  emit('mounted', api.value)
  nextTick(() => {
    setDefaultApi()
  })
})

</script>


<style scoped lang="scss">
.x-form {
  display: flex;
  box-sizing: border-box;
  flex-wrap: wrap;
  table {
    width: 100%;
    border: none;
    border-collapse: collapse;
  }
  .col {
    display: flex;
    box-sizing: border-box;
    margin-top: 5px;
    .title {
      box-sizing: border-box;
      text-align: right;
      padding-right: 5px;
      align-content: center;
      font-size: 13px;
      .required {
        display: inline-block;
        color: red;
      }
    }
    .item {

    }
  }
  .divider {
    height: 1px;
    margin: 3px 0;
    border-bottom: 1px solid rgba(0,0,0,0.2);
  }
}

</style>